#include "types.h"
#include "riscv.h"
#include "proc.h"
#include "defs.h"
#include "printf.h"

// 系统调用描述符
struct syscall_desc {
  int (*func)(void);   // 实现函数
  char *name;          // 系统调用名称
  int arg_count;       // 参数个数
};

// 系统调用号定义
enum {
  SYS_fork = 1,
  SYS_exit,
  SYS_wait,
  SYS_kill,
  SYS_getpid,
  SYS_write,
  SYS_read,
  SYS_sbrk,
  SYS_open,
  SYS_close,
  // ...可扩展
};

// 前向声明（在 sysproc.c/sysfile.c 中实现）
int sys_fork(void);
int sys_exit(void);
int sys_wait(void);
int sys_kill(void);
int sys_getpid(void);
int sys_write(void);
int sys_read(void);
int sys_sbrk(void);
int sys_open(void);
int sys_close(void);

// 系统调用表
struct syscall_desc syscall_table[] = {
  [0] = { NULL, NULL, 0 },  // 显式初始化索引 0，避免未初始化
  [SYS_fork]    = { sys_fork,    "fork",    0 },
  [SYS_exit]    = { sys_exit,    "exit",    0 },
  [SYS_wait]    = { sys_wait,    "wait",    0 },
  [SYS_kill]    = { sys_kill,    "kill",    0 },
  [SYS_getpid]  = { sys_getpid,  "getpid",  0 },
  [SYS_write]   = { sys_write,   "write",   3 },
  [SYS_read]    = { sys_read,    "read",    3 },
  [SYS_sbrk]    = { sys_sbrk,    "sbrk",    1 },
  [SYS_open]    = { sys_open,    "open",    2 },
  [SYS_close]   = { sys_close,   "close",   1 },
  // ...可扩展
};

// 参数提取辅助函数（从 trapframe 中取参数）
int argint(int n, int *ip) {
  struct proc *p = myproc();
  if (!p || !p->trapframe) return -1;
  switch (n) {
    case 0: *ip = p->trapframe->a0; break;
    case 1: *ip = p->trapframe->a1; break;
    case 2: *ip = p->trapframe->a2; break;
    case 3: *ip = p->trapframe->a3; break;
    case 4: *ip = p->trapframe->a4; break;
    case 5: *ip = p->trapframe->a5; break;
    default: return -1;
  }
  return 0;
}

int argaddr(int n, uint64 *ip) {
  struct proc *p = myproc();
  if (!p || !p->trapframe) return -1;
  switch (n) {
    case 0: *ip = p->trapframe->a0; break;
    case 1: *ip = p->trapframe->a1; break;
    case 2: *ip = p->trapframe->a2; break;
    case 3: *ip = p->trapframe->a3; break;
    case 4: *ip = p->trapframe->a4; break;
    case 5: *ip = p->trapframe->a5; break;
    default: return -1;
  }
  return 0;
}

// 系统调用分发器
void syscall_dispatch(void) {
  struct proc *p = myproc();
  if (!p || !p->trapframe) return;

  int num = p->trapframe->a7;
  int ret = -1;

  if (num > 0 && num < (sizeof(syscall_table)/sizeof(syscall_table[0])) && syscall_table[num].func) {
    ret = syscall_table[num].func();
  } else {
    printf("unknown syscall: %d\n", num);
  }

  p->trapframe->a0 = ret; // 返回值写回 a0
}



// 提取字符串参数（简化版：直接访问内核地址空间）
int argstr(int n, char *buf, int max) {
  uint64 addr;
  if (argaddr(n, &addr) < 0)
    return -1;
  
  // 简化实现：直接访问（内核线程模型下都在内核地址空间）
  // 注意：如果是用户态，需要使用copyinstr
  char *str = (char *)addr;
  int i;
  for (i = 0; i < max - 1 && str[i] != '\0'; i++) {
    buf[i] = str[i];
  }
  buf[i] = '\0';
  return i;
}